#region Using Directives

using System;
using System.IO;
using System.Windows.Forms;
using System.Globalization;
using Microsoft.VisualStudio.Modeling;
using Microsoft.Practices.ComponentModel;
using Microsoft.Practices.RecipeFramework;
using Microsoft.Practices.RecipeFramework.Library;
using Microsoft.Practices.RecipeFramework.Services;
using Microsoft.Practices.RecipeFramework.VisualStudio;
using Microsoft.Practices.RecipeFramework.VisualStudio.Templates;
using EnvDTE;
using EastBancTech.InstallerDefinition;
using Microsoft.Practices.Modeling.Dsl.Integration.Helpers;
using System.ServiceProcess;

#endregion

namespace EBT.Deployment.SoftwareFactory.Actions
{
    [ServiceDependency(typeof(DTE))]
    public abstract class AddComponentBase<T> : ActionBase where T : EastBancTech.InstallerDefinition.Component
    {
        String sourceDirectory;
        String fileSetName;
        Store wixPackageStore;
        ComponentPackage componentPackage;

        [Input(Required = true)]
        public ComponentPackage ComponentPackage
        {
            get { return componentPackage; }
            set { componentPackage = value; }
        }

        [Input(Required = true)]
        public String SourceDirectory
        {
            get { return sourceDirectory; }
            set { sourceDirectory = value; }
        }

        [Input(Required = true)]
        public Store WixPackageStore
        {
            get { return wixPackageStore; }
            set { wixPackageStore = value; }
        }

        [Input(Required = true)]
        public String FileSetName
        {
            get { return fileSetName; }
            set { fileSetName = value; }
        }

        protected abstract LinkedElementCollection<T> LinkedCollection
        {
            get;
        }

        protected override void OnExecute()
        {
            ComponentPackage cmpPackage = this.ComponentPackage as ComponentPackage;

            if (cmpPackage == null)
                throw new ApplicationException("Current DSL model does not contain 'ComponentPackage'");

            using (Transaction transaction = WixPackageStore.TransactionManager.BeginTransaction("Add new Component"))
            {
                T component = CreateComponent(cmpPackage);
                DomainModelHelper.AddLinkedElement<T>(LinkedCollection, component);

                FolderSource fldSrc = cmpPackage.Store.ElementFactory.CreateElement(FolderSource.DomainClassId) as FolderSource;
                fldSrc.path = SourceDirectory;
                fldSrc.FileSet = GetFilesetByName(FileSetName);
                component.FileSource = fldSrc;

                transaction.Commit();
            }
        }

        public override void Undo()
        {
            throw new Exception("The method or operation is not implemented.");
        }


        protected abstract T CreateComponent(ComponentPackage cmpPackage);

        private FileSet GetFilesetByName(String name)
        {
            foreach (FileSet fs in wixPackageStore.ElementDirectory.FindElements<FileSet>())
            {
                if (String.Compare(fs.Name, name, true) == 0)
                    return fs;
            }

            return null;
        }

    }
}
